home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / ABUSESRC.ZIP / AbuseSrc / abuse / src / sndserver.c < prev    next >
C/C++ Source or Header  |  1996-04-11  |  8KB  |  345 lines

  1. extern "C"
  2. {
  3. #include <sys/types.h>
  4. #include <stdio.h>
  5. #include <fcntl.h>
  6. #include <sys/ioctl.h>
  7. #include <unistd.h>
  8. #include <stdlib.h>
  9. #include <malloc.h>
  10. #include <sys/stat.h>
  11. #include <linux/soundcard.h>
  12. #include <sys/time.h>
  13. #include "DoomDef.h"
  14. };
  15.  
  16. #include "sndserver.h"
  17. #include "wadread.h"
  18.  
  19. #define SOUNDDIR LIBDIR "/sfx/"
  20.  
  21. typedef struct wadinfo_struct
  22. {
  23.   char    identification[4];        // should be IWAD
  24.   int    numlumps;
  25.   int    infotableofs;
  26. } wadinfo_t;
  27.  
  28. typedef struct filelump_struct
  29. {
  30.   int    filepos;
  31.   int    size;
  32.   char    name[8];
  33. } filelump_t;
  34.  
  35. static int mytime = 0;        // an internal time keeper
  36. int numsounds;            // number of sound effects
  37. int longsound;            // longest sound effect
  38. int lengths[NUMSFX];        // lengths of all sound effects
  39. unsigned char mixbuffer[MIXBUFFERSIZE];    // mixing buffer
  40. int sfxdevice;            // file descriptor of sfx device
  41. int musdevice;            // file descriptor of music device
  42. unsigned char *channels[8];    // the channel data pointers
  43. unsigned char *channelsend[8];    // the channel data end pointers
  44. int channelstart[8];        // time that the channel started playing
  45. int channelhandles[8];        // the channel handles
  46.  
  47. static void derror(char *msg)
  48. {
  49.   fprintf(stderr, "error: %s\n", msg);
  50.   exit(-1);
  51. }
  52.  
  53. int mix(void)
  54. {
  55.  
  56.   register int i, j, d;
  57.  
  58. //  if (channels[0]) fprintf(stderr, ".");
  59.  
  60. //  for (d=i=0 ; i<8 ; i++)
  61. //    d |= (int) channels[i];
  62. //  if (!d) return 0;
  63.  
  64.   // mix into the mixing buffer
  65.   for (i=0 ; i<MIXBUFFERSIZE ; i++)
  66.   {
  67.     d = 0;
  68.     j = 8;
  69.     do {
  70.       if (channels[--j])
  71.       {
  72.         d += *channels[j]++ - 128;
  73.       }
  74.     } while (j);
  75.     if (d > 127) mixbuffer[i] = 255;
  76.     else if (d < -128) mixbuffer[i] = 0;
  77.     else mixbuffer[i] = (unsigned char) (d+128);
  78. //    if (d > 127) mixbuffer[i] = 0;
  79. //    else if (d < -128) mixbuffer[i] = 255;
  80. //    else mixbuffer[i] = (unsigned char) (-d+127);
  81.   }
  82.  
  83.   // check for freed channels
  84.   for (j=0 ; j<8 ; j++)
  85.   {
  86.     if (channels[j] == channelsend[j]) channels[j] = 0;
  87.   }
  88.  
  89.   return 1;
  90.  
  91. }
  92.  
  93. void grabdata(int c, char **v)
  94. {
  95.  
  96.   int i;
  97.  
  98.   numsounds = NUMSFX;
  99.   longsound = 0;
  100.  
  101.   openwad("../frame/doom.wad");
  102.  
  103.   for (i=1 ; i<NUMSFX ; i++)
  104.   {
  105.     if (!S_sfx[i].link)
  106.     {
  107.       S_sfx[i].data = getsfx(S_sfx[i].name, &lengths[i]);
  108.       if (longsound < lengths[i]) longsound = lengths[i];
  109.     } else {
  110.       S_sfx[i].data = S_sfx[i].link->data;
  111.       lengths[i] = lengths[(S_sfx[i].link - S_sfx)/sizeof(struct sfxinfo_t)];
  112.     }
  113.     /*
  114.     // test only
  115.     {
  116.       int fd;
  117.       char name[10];
  118.       sprintf(name, "sfx%d", i);
  119.       fd = open(name, O_WRONLY|O_CREAT, 0644);
  120.       write(fd, S_sfx[i].data, lengths[i]);
  121.       close(fd);
  122.     }
  123.     */
  124.   }
  125.  
  126. }
  127.  
  128. void opensfxdev(int c, char **v)
  129. {
  130.  
  131.   int i, rc;
  132.  
  133.   // open the sound device
  134.   sfxdevice = open("/dev/dsp", O_WRONLY, 0);
  135.   if (sfxdevice < 0) derror("Could not open /dev/dsp");
  136.  
  137.   // set it up for the proper sound format
  138.   i = 8;
  139.   rc = ioctl(sfxdevice, SNDCTL_DSP_SAMPLESIZE, &i);
  140.   if (rc < 0) fprintf(stderr, "SAMPLESIZE failed\n");
  141.   i = 11111;
  142.   rc = ioctl(sfxdevice, SNDCTL_DSP_SPEED, &i);
  143.   if (rc < 0) fprintf(stderr, "SPEED failed\n");
  144.   i = 0;
  145.   rc = ioctl(sfxdevice, SNDCTL_DSP_STEREO, &i);
  146.   if (rc < 0) fprintf(stderr, "STEREO failed\n");
  147. //  i = 2;
  148. //  rc = ioctl(sfxdevice, SNDCTL_DSP_SUBDIVIDE, &i);
  149. //  if (rc < 0) fprintf(stderr, "SUBDIVIDE failed\n");
  150.  
  151. }
  152.  
  153. void closesfxdev(void)
  154. {
  155.   close(sfxdevice);
  156. }
  157.  
  158. void openmusdev(int c, char **v)
  159. {
  160. }
  161.  
  162. void closemusdev(void)
  163. {
  164. }
  165.  
  166. static struct timeval last={0,0}, now;
  167. static struct timezone whocares;
  168.  
  169. void updatesounds(void)
  170. {
  171.   int deltatime;
  172.   int rc;
  173.  
  174.   rc = mix();
  175.   rc = ioctl(sfxdevice, SNDCTL_DSP_POST, 0);
  176. //  rc = ioctl(sfxdevice, SNDCTL_DSP_SYNC, 0);
  177.   if (rc < 0) fprintf(stderr, "SYNC failed?!\n");
  178.   write(sfxdevice, mixbuffer, MIXBUFFERSIZE);
  179. /*
  180.   gettimeofday(&now, &whocares);
  181.   deltatime = (now.tv_sec - last.tv_sec)*1000000 + now.tv_usec - last.tv_usec;
  182.   deltatime = deltatime - (1 * MIXBUFFERSIZE * 1000000) / (1 * SPEED);
  183.   last = now;
  184.   if (deltatime < 0)
  185.     usleep (-deltatime);
  186.   if (rc)
  187.   {
  188.     write(sfxdevice, mixbuffer, MIXBUFFERSIZE);
  189.     fprintf(stderr, ".");
  190.   }
  191. */
  192. }
  193.  
  194. int addsfx(int sfxid, int volume)
  195. {
  196.  
  197.   int i;
  198.   int rc = -1;
  199.   static unsigned short handlenums = 0;
  200.   int oldest = mytime;
  201.   int oldestnum = 0;
  202.  
  203.   for (i=0 ; i<8 ; i++)
  204.   {
  205.     if (!channels[i])
  206.     {
  207.       channelsend[i] =
  208.         (channels[i] = (unsigned char *) S_sfx[sfxid].data) + lengths[sfxid];
  209.       if (!handlenums) handlenums = 100;
  210.       channelhandles[i] = rc = handlenums++;
  211.       channelstart[i] = mytime;
  212.       break;
  213.     }
  214.     else
  215.     {
  216.       if (channelstart[i] < oldest)
  217.       {
  218.         oldestnum = i;
  219.     oldest = channelstart[i];
  220.       }
  221.     }
  222.   }
  223.  
  224.   // if no channels were available, kill oldest sound and replace it
  225.   if (i == 8)
  226.   {
  227.     channelsend[oldestnum] =
  228.       (channels[oldestnum] = (unsigned char *) S_sfx[sfxid].data)
  229.        + lengths[sfxid];
  230.     if (!handlenums) handlenums = 100;
  231.     channelhandles[oldestnum] = rc = handlenums++;
  232.     channelstart[i] = mytime;
  233.   }
  234.  
  235.   return rc;
  236.  
  237. }
  238.  
  239. void outputushort(int num)
  240. {
  241.  
  242.   static unsigned char buff[5] = { 0, 0, 0, 0, '\n' };
  243.   static char *badbuff = "xxxx\n";
  244.  
  245.   // outputs a 16-bit # in hex or "xxxx" if -1.
  246.   if (num < 0)
  247.   {
  248.     write(1, badbuff, 5);
  249.   } else {
  250.     buff[0] = num>>12;
  251.     buff[0] += buff[0] > 9 ? 'a'-10 : '0';
  252.     buff[1] = (num>>8) & 0xf;
  253.     buff[1] += buff[1] > 9 ? 'a'-10 : '0';
  254.     buff[2] = (num>>4) & 0xf;
  255.     buff[2] += buff[2] > 9 ? 'a'-10 : '0';
  256.     buff[3] = num & 0xf;
  257.     buff[3] += buff[3] > 9 ? 'a'-10 : '0';
  258.     write(1, buff, 5);
  259.   }
  260.  
  261. }
  262.  
  263. void initdata(void)
  264. {
  265.   int i;
  266.   for (i=0 ; i<sizeof(channels)/sizeof(unsigned char *) ; i++) channels[i] = 0;
  267.   gettimeofday(&last, &whocares);
  268.   usleep(100000);
  269. }
  270.  
  271. int main(int c, char **v)
  272. {
  273.  
  274.   int done = 0;
  275.   int rc, nrc, sndnum, handle = 0;
  276.   unsigned char commandbuf[10];
  277.   fd_set fdset, scratchset;
  278.   struct timeval zerowait = { 0, 0 };
  279.  
  280.   grabdata(c, v);    // get sound data
  281.   initdata();        // init any data
  282.  
  283.   opensfxdev(c, v);    // open sfx device
  284.   openmusdev(c, v);    // open music device
  285.   fprintf(stderr, "ready\n");
  286.  
  287.   // parse commands and play sounds until done
  288.   FD_ZERO(&fdset);
  289.   FD_SET(0, &fdset);
  290.   while (!done)
  291.   {
  292.     mytime++;
  293.     do {
  294.       scratchset = fdset;
  295.       rc = select(FD_SETSIZE, &scratchset, 0, 0, &zerowait);
  296.       if (rc > 0)
  297.       {
  298.   //      fprintf(stderr, "select is true\n");
  299.     // got a command
  300.     nrc = read(0, commandbuf, 1);
  301.     if (!nrc) { done = 1; rc = 0; }
  302.     else {
  303.       switch (commandbuf[0])
  304.       {
  305.         case 'p':         // play a new sound effect
  306.           read(0, commandbuf, 3);
  307.           commandbuf[0] -= commandbuf[0]>='a' ? 'a'-10 : '0';
  308.           commandbuf[1] -= commandbuf[1]>='a' ? 'a'-10 : '0';
  309.           sndnum = (commandbuf[0]<<4) + commandbuf[1];
  310.   //        fprintf(stderr, "cmd: play sound %d\n", sndnum);
  311.           handle = addsfx(sndnum, 127); // returns the handle
  312. //          outputushort(handle);
  313.           break;
  314.         case 'q':
  315.           read(0, commandbuf, 1);
  316.           done = 1; rc = 0;
  317.           break;
  318.         case 's':
  319.           {
  320.             int fd;
  321.         read(0, commandbuf, 3);
  322.         commandbuf[2] = 0;
  323.         fd = open((char*)commandbuf, O_CREAT|O_WRONLY, 0644);
  324.         commandbuf[0] -= commandbuf[0]>='a' ? 'a'-10 : '0';
  325.         commandbuf[1] -= commandbuf[1]>='a' ? 'a'-10 : '0';
  326.         sndnum = (commandbuf[0]<<4) + commandbuf[1];
  327.         write(fd, S_sfx[sndnum].data, lengths[sndnum]);
  328.         close(fd);
  329.           }
  330.           break;
  331.         default:
  332.           fprintf(stderr, "Did not recognize command\n");
  333.           break;
  334.       }
  335.     }
  336.       }
  337.     } while (rc > 0);
  338.     updatesounds();
  339.   }
  340.  
  341.   closesfxdev();
  342.   closemusdev();
  343.  
  344. }
  345.